计算机网络(四)——传输层

TCP和UDP协议;TCP的各种机制(面向连接的可靠服务、序号、确认、窗口、拥塞控制等),TCP传输连接管理,TCP的有限状态机。
传输层传输的数据单位是segment,TCP中叫报文段,UDP中叫用户数据报。
运输层向它上面的应用层提供通信服务。
它是面向通信的最高层,同时也是用户功能的最底层。通信子网中没有运输层,运输层只存在于通信子网外的主机中。

TCP/IP体系中的传输层

端口

TCP和UDP都使用了端口(port)与应用进程进行通信。复用和分用都需要端口才能实现。端口用16 bit端口号进行标识。
网络层为主机之间提供逻辑通信,而传输层为应用进程之间提供端到端逻辑通信。
应用层程序固定使用的熟知端口(well-known port):

应用程序 FTP TELNET SMTP DNS TFTP HTTP SNMP SNMP(trap)
熟知端口 21 23 25 53 69 80 161 162

插口

TCP连接的端点称为插口(socket,套接字、套接口)。对于无连接的UDP,虽然相互通信的进程之间没有虚连接,但发送端和接收端也有端口,同样有插口概念。

应用和应用层协议主要使用的传输层协议(UDP和TCP协议)

应用 应用层协议 传输层协议
名字转换 DNS UDP
简单文件传送 TFTP UDP
路由选择(网络层) RIP UDP
IP地址配置 BOOTP, DHCP UDP
网络管理 SNMP UDP
远程文件服务器 NFS UDP
IP电话 专用协议 UDP
流式多媒体信息 专用协议 UDP
多播(网络层) IGMP UDP
电子邮件 SMTP TCP
远程终端接入 TELNET TCP
万维网 HTTP TCP
文件传送 FTP TCP

UDP/TCP与应用层之间的端口都是用报文队列来实现的,客户端或服务器端各有一个出队列和入队列。

UDP(user datagram protocol,用户数据报协议)

特点

(1) 发送数据前不需要建立连接,减少了开销和发送数据之前的时延;
(2) 不使用拥塞控制,因此网络拥塞不会使源主机的发送速率降低;
(3) 也不保证可靠交互,因此主机不需要维持具有许多参数的复杂状态表;
(4) UDP首部8字节,比TCP首部20字节少。IP数据报的协议字段中,UDP的协议号为17。
(5) UDP是在IP数据报的基础上增加了端口(有了端口,就能进行复用和分用)和差错检测功能。

报文队列

为了对UDP的不可靠传输进行适量改进以减少数据的丢失,可以使用向前纠错或重传已丢失的报文。
UDP与应用程序之间的端口都是用报文队列来实现的。下图以UDP使用TFTP(简单文件传输协议)为例。
UDP用户数据报

TFTP服务器一直在运行,等待TFTP客户服务器的请求。服务器端使用熟知端口号69(TFTP)。当客户进程启动时,操作系统就请求一个临时分配的端口号,然后操作系统为该进程创建两个队列:出队列和入队列。客户进程将报文发至出队列,加上UDP首部,然后发送至IP(网络)层。出队列有可能溢出,则操作系统通知应用层的TFTP进程暂停发送。
客户进程接收来自IP层的报文时,先判断是否是目的端口号,如不正确就丢弃该报文,并请ICMP发送“端口不可达”差错报文给服务器端;若目的端口号正确,则UDP将收到的报文放在入队列队尾,客户进程按队列的先后顺序将其一并取走。入队列也可能发生队列溢出,如果溢出则丢弃但不通知对方,这里没有流量控制机制来通知对方降低发送速率,并请ICMP发送“端口不可达”差错报文给服务器。

UDP首部格式

UDP用户数据报的首部和伪首部
UDP计算检验和的方式和IP数据报首部检验和的方法类似。不同之处在于IP数据报只检验IP数据报的首部,而UDP是将首部和数据部分一起都检验。而由于UDP数据报是在IP数据报的开头添加的UDP数据报首部,所以UDP的检验和既检查了UDP用户数据报的源端口号和目的端口号以及用户数据报的数据部分,又检查了IP数据报的源IP地址和目的IP地址。
伪首部:只是为了计算校验和而存在,并不真实存在。

TCP(transfer control protocol,传输控制协议)

TCP报文段首部(20字节<=TCP首部长度<=60字节)

TCP提供全双工的可靠的交互服务。
在IP数据报协议字段中,TCP协议号为6。
TCP报文段的全部功能都体现在TCP首部各字段中。
TCP报文的首部

源端口和目的端口

各占2个字节。端口是传输层和应用层之间的接口,传输层的复用和分用功能都要通过端口才能实现。

序号

占4个字节。TCP是面向数据流的,把TCP连接中的每个数据流都编上序号,其中序号值是本报段发送的第一个字节的序号。如一个报文段序号字段值为201,所携带的数据有100字节,则数据的最后一个字节的序号为300,而下一个报文的序号字段值为301。

确认号

占4个字节。确认号字段的内容是期望收到的下一个报文段序号字段值。如A收到了一段报文,序号值为201,数据长度为100,则最后一个字节的序号为300,则确认号为301。与ACK比特位配合使用,ACK=1时确认字段才有效。
若发送M0,接收端收到后发回ACK1(携带了接收端的数据,表明期望收到下一个报文M1)。(与后面的快重传算法对比,发送M0,接收端收到后立即发送ACK0,而不是在自己需要发送数据时才将ACK捎带上。注意收到一个ACKn,表明前面的n个数据都收到了。)

数据偏移

占4 bit。由于TCP报文首部长度不固定,数据偏移字段指出了TCP报文数据起始距报文起始处有多远。由于4 bit所能表示的最大值为15,因此数据偏移的最大值为60字节,即TCP首部的最长长度。

保留

特殊的比特位

a. URG(紧急比特位,urgent) URG=1,表示有紧急数据,需要优先发送。如若要取消该程序,从键盘发出中断命令Ctrl C。URG与紧急指针字段配合使用。紧急指针指出本报文中最后一个紧急数据的字节序号。
b. ACK(确认比特位,acknowledge)
c. PSH(推送比特位,push)当两个应用进程进项交互式通信时,有时一端应用进程希望在键入一个命令后能够立刻得到对方的回应,而不需要整个缓存满再向上交付。
d. RST(复位比特位,reset)RST=1表明TCP连接中出现严重差错,需要释放连接,重新建立TCP连接;也可用于拒绝一个非法报文或拒绝打开一个连接。
e. SYN(同步比特位,synchronize)在连接建立时用来同步序列。
若SYN=1, ACK=0,表明这是一个请求连接报文段;若对方同意连接请求,则在响应报文段中使SYN=1, ACK=1。
f. FIN(终止比特位,final)FIN=1,释放连接,此报文段的数据发送完毕,要求释放传输连接。

窗口

占2个字节。即滑动窗口,用来控制对方发送数据量,单位为字节。计算机网络通常是根据接收端的接收能力来控制发送端的数量。若A确定自己的接收能力(窗口值)大小为WIN,则A发送给B的报文段中应该写入WIN的值。

检验和

占2个字节。

选项

选项字段的长度可变,它规定了MSS(maximum segment size,最大报文长度),没有用此字段时,默认首部长度为20字节。
若TCP报文非常长,则在IP层传输时可能要分成多个片,容易出错,也使开销增大。在连接建立时双方都把自己的MSS写入报文,取较小的那个(报文长=首部长+MSS长)。默认536字节,则主机所能接收的报文长为536+20=556。

TCP的数据编号与确认

TCP传输的可靠是因为使用了序号与确认。TCP发送一段报文,它同时在自己的重传队列中存放一个副本,若收到ACK,则删除该副本。
由于TCP连接能提供全双工通信,因此通信中的每一方都不必专门发送确认字段,而只是在传送数据时顺便把确认信息捎带传送,这样可以提高传输效率。
TCP有三种机制控制报文段的发送:
a. TCP维护一个MSS变量,当发送缓存从发送进程中得到的数据量达到MSS字节,则组装成TCP报文段发送出去;
b. TCP的PSH=1(推送)操作;
c. 发送端计时器到了。
如何控制发送报文段的时机:使用Negle算法。先发送一个字符,得到确认后再将缓存中的数据组装成报文段发送出去;在收到对前一个报文段的确认才继续发送下一个报文段。算法还规定,当到达的字符以达到窗口的一半或达到MSS,则立即发送。但Negle算法容易导致糊涂窗口综合征(silly window syndrome)。

TCP的流量控制和拥塞控制

采用可变的滑动窗口进行流量控制,窗口大小为字节。TCP报文段首部的窗口字段就是给对方设置窗口数值的上限。
发送窗口在连接建立时由双方商定,但在同信道过程中,接收端可以根据自己的资源情况,随时动态地控制发送端的窗口大小。

利用可变窗口进行流量控制举例

传输层拥塞控制算法:慢开始(slow-start)、拥塞避免(congestion avoidance)、快重传(fast retransmit)、快恢复(fast recovery)

慢开始和拥塞避免

接收窗口(rwnd,receiver window)是来自接收端的流量控制,是接收端根据目前缓存的大小所许诺的最新窗口值;
拥塞窗口(cwnd,congestion window)是来自发送端的流量控制,是发送端根据自己的流量拥塞情况而设置的窗口值。
发送窗口是取接收窗口和拥塞窗口中的最小值,即t_wnd = min{rwnd, cwnd}
a. 慢开始算法
由小到大逐步增大拥塞窗口(cwnd)的值。通常先将cwnd设置为MSS(最大报文段),每接收到一个新报文段的ACK,则将cwnd增大一个MSS数值。这样做使分组注入到网络的速率更加合理。但这样做容易导致cwnd增长过快,cwnd的大小是按指数增长的。
例:在一开始,先将cwnd=1,发送第一个报文M0,接收端收到后发回ACK1(表示期望收到的下一个报文为M1)。发送端收到ACK1后,将cwnd+1,于是就可以发送两个报文M1和M2。接收端收到后发回ACK3和ACK4,发送端接收到ACK3和ACK4后,又将自己的cwnd+1+1,即每收到一个ACK,cwnd就加1。
b. 拥塞避免算法
发送端的cwnd(拥塞窗口)每经过一次RTT(round trip time,往返时延)就增加一个MSS大小(拥塞避免算法也叫“加法增大”)。这种cwnd大小的增长是线性的,比慢开始算法的拥塞窗口增长速率慢得多。
c. 慢开始和拥塞避免算法的结合
为了防止拥塞窗口的快速增长引起网络拥塞,需要设置ssthresh(slow start threshold,慢开始门限)
若cwnd < ssthresh,使用慢开始算法;
若cwnd > ssthresh,使用拥塞避免算法;
若cwnd = ssthresh,两种算法都可以。
无论在慢开始阶段还是拥塞避免阶段,只要出现了网络拥塞(即网络出现超时),就将ssthresh(慢开始门限)的值减小到一半(但不能小于2)(这一步也叫“乘法减小”);然后cwnd=1(拥塞窗口降为1),重新开始慢开始算法。(这样做的缺点是网络不能很快地恢复到正常状态。)

慢开始和拥塞避免算法举例

快重传和快恢复

慢开始和拥塞避免算法是TCP中最早使用的拥塞控制算法。有时在TCP连接中国会出现一种情况:发送端发送的Mn数据丢失,接收端只能返回ACK(n-1),若此时为Mn设置的超时定时没有到,发送端继续发送后面的数据,会出现接收端返回多个ACK(n-1)的情况,直到Mn的超时定时器到了才重传Mn,为了避免这种情况,又增加了两个新的算法。
a. 快重传算法
发送端只要收到n个(一般为3个)重复的ACK即可判定有报文段丢失了,就应该立即重传丢失的报文段,而不是等待这个报文段的超时定时器到了。快重传算法在某些情况下可以更早地重传丢失的报文段。
b. 快恢复算法
前面的慢开始和拥塞避免算法中,只要出现网络拥塞,就将cwnd(拥塞窗口)降为1,然后执行慢开始算法,其缺点是网络不能很快地恢复到正常工作状态。
a) 建立TCP连接时使用慢开始算法;
b) 当发送端收到n个重复ACK时,就将ssthresh(慢开始门限)的值减小到一半(但不能小于2);
c) 然后cwnd=ssthresh+n*MSS(拥塞窗口增大了n*MSS),重新开始慢开始算法;(这样做是因为已经有n个分组离开了网络,因此拥塞窗口扩大并不会加剧网络拥塞。而拥慢开始和拥塞避免算法中是将cwnd降为1。)
d) 若发送窗口值还允许发送报文段,则按拥塞避免算法继续发送报文段;
e) 若收到了确认新报文的ACK,则将cwnd缩小到ssthresh。

TCP的重传机制

TCP每发送一个报文,就对这个报文设置一次定时器,当定时器设置的重传时间到了但还没有收到确认,则重传这一段报文。
报文段的往返时延:报文发出时间与收到相应确认报文的时间之差。平均RTT(round trip time,往返时延):
平均RTT=a*旧的RTT+(1-a)新的往返时延样本
运输层使用一种自适应算法设置RTO(retransmission time-out,超时重传时间):
RTO=b*RTT(其中b>1,通常取2)

TCP的传输连接管理

TCP是面向连接的,因此传输连接分三个阶段:建立连接、数据传送、释放连接。
TCP的连接和建立是采用客户-服务器方式。SYN同步比特位,SEQ报文序列号,ACK确认号(表示期望A发送的下一个报文段序号字段的值)
TCP的三次握手和四次挥手

三次握手建立连接

四次挥手释放连接

具体三次握手和四次挥手过程请见:TCP的三次握手和四次挥手

TCP的有限状态机

为了管理因特网,在网络管理中心设有管理信息库(MIB,management information base),里面存放着各主机的TCP连接表(connection table),如下

TCP的连接表

有限状态机:TCP可能处于的状态和各状态可能发生的变迁,如下

其中粗实线表示对客户进程的正常变迁,粗虚线表示对服务进程的正常变迁,细线箭头表示非正常变迁。